package com.smartcommunity.controller.people;

import com.alibaba.fastjson.JSONObject;
import com.smartcommunity.api.user.UserApi;
import com.smartcommunity.base.bean.PeopleFaceVid;
import com.smartcommunity.bean.constant.Constant;
import com.smartcommunity.bean.entity.User;
import com.smartcommunity.bean.enumeration.JudgeEnum;
import com.smartcommunity.bean.enumeration.ResultCode;
import com.smartcommunity.bean.model.Pager;
import com.smartcommunity.bean.model.Result;
import com.smartcommunity.controller.BaseController;
import com.smartcommunity.entity.people.People;
import com.smartcommunity.entity.people.PeopleSearchModel;
import com.smartcommunity.entity.people.RealPeopleHouseMove;
import com.smartcommunity.entity.people.dto.AddPeopleDto;
import com.smartcommunity.entity.people.dto.HouseDto;
import com.smartcommunity.entity.people.dto.UpdatePeopleDto;
import com.smartcommunity.log.interceptor.Log;
import com.smartcommunity.service.CommonService;
import com.smartcommunity.utils.ArrayUtils;
import com.smartcommunity.service.people.PeopleService;
import com.smartcommunity.utils.ToolDateTime;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;

/**
 * @version V1.5.0
 * @ClassName: PeopleController
 * @Description: 人员控制层
 * @author: minsheng
 * @Date: 2019/1/10 17:45
 * @Company:
 */
@RestController
@RequestMapping(value = "/people")
@Api(value = "小区服务-实有人口", tags = "实有人口")
@Slf4j
public class PeopleController extends BaseController {

    @Autowired
    private PeopleService peopleService;

    @Autowired
    private UserApi userApi;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private CommonService commonService;

    /**
     * 查询所有人员信息
     *
     * @param credentialNo
     * @param peopleName
     * @param pageNumber
     * @param pageSize
     * @return
     */
    @GetMapping(value = "/pageAllPeoples")
    @ApiOperation(value = "人口列表", notes = "人口列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNumber", value = "页码"),
            @ApiImplicitParam(name = "pageSize", value = "页数"),
            @ApiImplicitParam(name = "credentialNo", value = "证件号码"),
            @ApiImplicitParam(name = "peopleName", value = "姓名"),
    })
    @Log(info = "查询实有人口列表分页信息",module = "实有人口",function = "查询")
    public Pager<People> pageAllPeoples (@RequestParam(required = false, name = "credentialNo") String credentialNo,
                                         @RequestParam(required = false, name = "peopleName") String peopleName,
                                         @RequestParam(required = false, name = "pageNumber") String pageNumber,
                                         @RequestParam(required = false, name = "pageSize") String pageSize) {
        Map<String, Object> queryMap = new HashMap<String, Object>();
        queryMap.put("credentialNo", credentialNo);
        queryMap.put("peopleName", peopleName);
        return peopleService.getAllPeople(queryMap, getPageNumber(pageNumber), getPageSize(pageSize));
    }

    /**
     * 实有人口列表
     * @param model
     * @return
     */
    @PostMapping(value = "/listPeoples")
    @ApiOperation(value = "实有人口列表", notes = "实有人口列表")
    @Log(info = "查询实有人口列表分页信息",module = "实有人口",function = "查询")
    public Pager<People> listPeoples (@RequestBody PeopleSearchModel model) {
        log.info("接口：listPeoples；实有人口列表。");
        long st=System.currentTimeMillis();
        People people = new People();
        people.setHouseNo(model.getHouseNo());
        people.setVid(model.getVid());
        people.setText(model.getText());
        people.setBuildingNo(model.getBuildingNo());
        people.setFeatureId(model.getFeatureId());
        people.setDomicileAddress(model.getDomicileAddress());

        String villageCode = request.getParameter("villageCode");
        if(StringUtils.isNotBlank(villageCode)){
            //people.setVillageCode(villageCode.replaceAll("'",""));
            people.setVillageCode(villageCode);
        }
        //判断小区code,为空则通过parentId查找所有小区
        if (StringUtils.isNotEmpty(model.getVillageCode())) {
            people.setVillageCode(model.getVillageCode());
        } else {
            if (StringUtils.isNotEmpty(model.getParentId())) {
                String orgIds = commonService.getAllChildOrgId(model.getParentId());
                Map<String, Object> map = new HashedMap();
                map.put("orgId", orgIds);
                map.put("villageCode", villageCode);
                List<String> villageList = commonService.listVillageCodeByOrgId(map);
                //此行政区划节点下没有小区，则返回
                if (villageList == null || villageList.size() == 0) {
                    return new Pager<>();
                }
                people.setVillageCode(ArrayUtils.toString(villageList));
            }
        }

        if (StringUtils.isNotEmpty(model.getPeopleType())) {
            people.setPeopleType(Integer.valueOf(model.getPeopleType()));
        }
        if (StringUtils.isNotEmpty(model.getMerge())) {
            people.setMerge(model.getMerge());
        }
        people.setCredentialNo(model.getCredentialNo());
        people.setPeopleName(model.getPeopleName());
        people.setGenderCode(StringUtils.isNotEmpty(model.getGenderCode())?Integer.parseInt(model.getGenderCode()):null);
        people.setNation(model.getNation());
        people.setResidenceAddress(model.getResidenceAddress());
        people.setPhoneNo(model.getPhoneNo());
        // 实有人口
        if (StringUtils.isNotEmpty(model.getLabel())) {
            people.setLabel(model.getLabel());
        }
        people.setIsVid(model.getIsVid());
        people.setIsLeave(model.getIsLeave());

        String year = ToolDateTime.formatSimpleDay(new Date()).substring(0, 4);
        // 判断开始年龄段有值的话，就查大于等于开始年龄段的
        String ageStart = model.getAgeStart();
        if (StringUtils.isNotBlank(model.getAgeStart()) && StringUtils.isBlank(model.getAgeEnd())) {
            ageStart = String.valueOf(Integer.valueOf(year) - Integer.valueOf(model.getAgeStart()));
            people.setBirthDateEnd(ageStart);
        }else{
            // 判断开始年龄段和结束年龄段都有值的话就查询区间的，判断没有值的话，就查询所有的
            String ageEndMiddleValue = "";
            if (StringUtils.isNotEmpty(model.getAgeStart())) {
                ageEndMiddleValue = String.valueOf(Integer.valueOf(year) - Integer.valueOf(model.getAgeStart()));
            }
            people.setBirthDateEnd(ageEndMiddleValue);

            if (StringUtils.isNotEmpty(model.getAgeEnd())) {
                ageStart = String.valueOf(Integer.valueOf(year) - Integer.valueOf(model.getAgeEnd()));
            }
            people.setBirthDateStart(ageStart);
        }

        if (model.getIsPic() != null) {
            //将是否包含图片 条件 放在idCardPic字段查询
            people.setIdCardPic(String.valueOf(model.getIsPic()));
        }
        if (model.getIds() != null) {
            //将是实有人口的id列表 放在remarks字段查询
            people.setRemarks(model.getIds());
        }
        people.setUseCacheTotalCount(model.isUseCacheTotalCount());
        if (!StringUtils.isEmpty(model.getResidentiaType())){
            people.setResidentiaType(Integer.valueOf(model.getResidentiaType()));
        }
        long speedTime=System.currentTimeMillis()-st;
        log.info("1.封装人口查询条件耗时:"+speedTime+"ms");
        Pager<People> peoplePager = peopleService.listPeoples(people,getPageNumber(String.valueOf(model.getPageNumber())), getPageSize(String.valueOf(model.getPageSize())), model.getSortField(), model.getSortModel());

        speedTime=System.currentTimeMillis()-st;
        log.info("总耗时:"+speedTime+"ms");
        return peoplePager;
    }


    /**
     * @Description: 根据小区编号查询实有人口数量
     * @param: [villageCode]
     * @return: int
     * @author: minsheng
     * @date: 2019/1/10 15:25
     */
    @PostMapping(value = "/countPeoples")
    @ApiOperation(value = "根据小区编号查询实有人口数量", notes = "根据小区编号查询实有人口数量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "villageCode", value = "小区编号")
    })
    @Log(info = "查询实有人口数量",module = "实有人口",function = "查询")
    public int countPeoples (@RequestParam(required = false, name = "villageCode") String villageCode) {
        log.info("接口：countPeoples；根据小区编号查询实有人口数量");
        int t = 0;
        People people = new People();
        people.setVillageCode(villageCode);
        // 实有人口
        people.setSourceSyrk("1");
        try {
            t = peopleService.countPeoples(people);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return t;
    }

    /**
     * @Description: 实有人口分类统计(包含标签)
     * @param: [villageCode]
     * @return: java.util.Map<java.lang.String   ,   java.lang.Object>
     * @author: minsheng
     * @date: 2019/1/10 15:25
     */
    @GetMapping(value = "/countPeopleByType")
    @ApiOperation(value = "实有人口分类统计", notes = "实有人口分类统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "villageCode", value = "小区编号")
    })
    @Log(info = "查询实有人口分类统计信息",module = "实有人口",function = "查询")
    public Result countPeopleByType (@RequestParam(required = false, name = "villageCode") String villageCode) {
        log.info("接口：countPeopleByType；实有人口分类统计");
        if(StringUtils.isEmpty(villageCode)){
            return Result.ok();
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("villageCode",villageCode);
        paramMap.put("type", Constant.PEOPLETYPE);
        Map<String, Object> map = peopleService.countPeopleByTypeEs(paramMap);
        return Result.ok(map);
    }

    /**
     * @Description: 居住类型统计
     * @param: [villageCode]
     * @return: java.util.Map<java.lang.String   ,   java.lang.Object>
     * @author: minsheng
     * @date: 2019/1/10 15:25
     */
    @GetMapping(value = "/countResidentiaType")
    @ApiOperation(value = "居住类型分类统计", notes = "居住类型分类统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "villageCode", value = "小区编号")
    })
    @Log(info = "查询实有人口分类统计信息",module = "实有人口",function = "查询")
    public Result countResidentiaTypeEs (@RequestParam(required = false, name = "villageCode") String villageCode) {
        log.info("接口：countResidentiaTypeEs；居住类型分类统计");
       /* if(StringUtils.isEmpty(villageCode)){
            return Result.ok();
        }*/
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("villageCode",villageCode);
        paramMap.put("type", Constant.RESIDENTIA_TYPE);
        Map<String, Object> map = peopleService.countResidentiaTypeEs(paramMap);
        return Result.ok(map);
    }


    @PostMapping(value = "/countByTag")
    @ApiOperation(value = "根据标签统计数据", notes = "根据标签统计数据")
    public Map<String, Object> countByTag (@RequestParam(name = "villageCode") String villageCode,
                                           @RequestParam(required = false, name = "groupId") String groupId) {
        log.info("接口：countByTag；根据标签统计数据。");
        Map<String, Object> param = new HashMap<>(2);
        param.put("villageCode",villageCode);
        param.put("groupId",groupId);
        return peopleService.countByTag(param);
    }

    @GetMapping (value = "/countByTagGroup")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "villageCode",required =true, value = "小区编号"),
            @ApiImplicitParam(name = "groupId",required =true, value = "标签组ID")
    })
    @Log(info = "查询标签组统计数据信息",module = "标签管理",function = "查询")
    @ApiOperation(value = "根据标签组统计数据", notes = "根据标签组统计数据")
    public Result<Integer> countByTagGroup (@RequestParam(required = true,name = "villageCode") String villageCode,
                                           @RequestParam(required = true, name = "groupId") String groupId) {
        log.info("接口：countByTagGroup；根据标签组统计数据。");
        return Result.ok(peopleService.countByTagGroup(villageCode,groupId));
    }

    /**
     * @Description: 获取人员基本信息
     * @param: [villageCode, credentialType, credentialNo]
     * @return: com.smartcommunity.entity.people.People
     * @author: minsheng
     * @date: 2019/1/10 15:25
     */
    @PostMapping(value = "/getPeopleBaseInfo")
    @Log(info = "查询实有人口基本信息",module = "实有人口",function = "查询")
    @ApiOperation(value = "获取人员基本信息", notes = "获取人员基本信息-以及住址，房屋，标签，车辆信息")
    public Result getPeopleBaseInfo (@RequestBody PeopleSearchModel model,
                                     HttpServletRequest request) {
        log.info("接口：getPeopleBaseInfo；获取人员基本信息。");
        Map<String, String> map = new HashMap<>(3);
        map.put("credentialNo", model.getCredentialNo());
        map.put("credentialType", model.getCredentialType());

        List<String> villageCodes = new ArrayList<>();
        User user = getCurrentUser();
        if (user != null && !user.isAdmin()) {
            Result<List<String>> result = userApi.getCurrentUserVillage(JudgeEnum.yes.getCode());
            if (!result.isOk()) {
                return result;
            }
            if(CollectionUtils.isNotEmpty(result.getData())) {
            	for(String tmp:result.getData()) {
            		villageCodes.add(tmp.replaceAll("'", ""));
            	}
            }
        }
        return Result.ok(peopleService.getPeopleBaseInfo(map, villageCodes));
    }

    @PostMapping(value = "/queryPeopleBaseInfo")
    @ApiOperation(value = "获取人员基本信息", notes = "获取人员基本信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "credentialNo", value = "证件号码")
    })
    @Log(info = "查询实有人口基本信息",module = "实有人口",function = "查询")
    public People queryPeopleBaseInfo (@RequestParam(name = "credentialNo") String credentialNo) {
        log.info("接口：queryPeopleBaseInfo；获取人员基本信息。");
        return peopleService.queryPeopleBaseInfo(credentialNo);
    }

    /**
     * 提供给车辆管理服务使用
     * @param credentialNo
     * @return
     */
    @PostMapping(value = "/queryPeopleInfo")
    @ApiOperation(value = "获取人员信息", notes = "获取人员信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "credentialNo", value = "证件号码") })
    @Log(info = "查询实有人口基本信息",module = "实有人口",function = "查询")
    public Result<String> queryPeopleInfo (@RequestParam(name = "credentialNo") String credentialNo) {
        log.info("接口：queryPeopleInfo；获取人员基本信息。");
        return Result.ok(JSONObject.toJSONString(peopleService.queryPeopleBaseInfo(credentialNo)));
    }

    @GetMapping(value = "/getLiveTogetherPeople")
    @ApiOperation(value = "获取同住人员基本信息", notes = "获取同住人员基本信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "credentialNo", value = "证件号码")
    })
    @Log(info = "查询同住人员基本信息",module = "实有人口",function = "查询")
    public List<People> getLiveTogetherPeople(
            @RequestParam(name = "credentialNo") String credentialNo) {
        log.info("接口：getLiveTogetherPeople；获取同住人员基本信息。");
        return peopleService.queryLiveTogetherPeople(credentialNo);
    }

    /**
     * 新增人员信息
     */
    @PostMapping(value = "/insertPeople")
    @Log(info = "新增人员信息",module = "实有人口",function = "新增")
    @ApiOperation(value = "新增人员信息", notes = "新增人员信息")
    public Result insertPeople (@Valid  @RequestBody @ApiParam(name = "addPeopleDto", value = "新增人员对象") AddPeopleDto addPeopleDto) {
        log.info("接口：insertPeople；新增人员信息");
        return peopleService.insertPeople(addPeopleDto);
    }

    /**
     * 删除实有人员
     *
     * @param credentialNos 证件号credentialNo（必填），多个证件号用“,”号进行分割，例如：321124521,2233115,1112235
     */
    @DeleteMapping(value = "/deletePeople")
    @Log(info = "删除人员信息",module = "实有人口",function = "删除")
    @ApiOperation(value = "删除实有人员", notes = "删除实有人员")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "credentialNos", value = "多个证件号用“,”号进行分割")
    })
    public Result deletePeople (@RequestParam(required = true, name = "credentialNos") String credentialNos) {
        log.info("接口：deletePeople；删除实有人员");
        return peopleService.deletePeople(credentialNos);
    }

    /**
     * 更新人员信息
     *
     */
    @PostMapping(value = "/updatePeople")
    @Log(info = "更新人员信息",module = "实有人口",function = "更新")
    @ApiOperation(value = "更新人员信息", notes = "更新人员信息")
    public Result updatePeople (@Valid  @RequestBody @ApiParam(name = "updatePeopleDto", value = "更新人员对象") UpdatePeopleDto updatePeopleDto) {
        log.info("接口：updatePeople；更新人员信息");
        return peopleService.updatePeople(updatePeopleDto);
    }


    @PostMapping(value = "/listAllPeoples")
    @ApiOperation(value = "根据条件查询人员信息(t_people表)", notes = "根据条件查询人员信息(t_people表)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "paramMap", value = "paramMap")
    })
    public List<People> listAllPeoples (@RequestBody Map<String, String> paramMap) {
        log.info("接口：listAllPeoples；根据条件查询人员信息(t_people)表");
        return peopleService.listAllPeoples(paramMap);
    }

    @PostMapping(value = "/listPeoplesByParam")
    @ApiOperation(value = "根据条件查询人员信息(包含人员标签)", notes = "根据条件查询人员信息(包含人员标签)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "param", value = "param")
    })
    public List<People> listPeoplesByParam (@RequestParam Map<String, String> param) {
        log.info("接口：listPeoplesByParam；根据条件查询人员信息(包含人员标签)");
        return peopleService.listPeoplesByParam(param);
    }


    /**
     * 获取视频身份VID
     */

    @PostMapping(value = "/getPeopleFaceVid")
    @Log(info = "查询视频身份VID信息",module = "实有人口",function = "更新")
    public PeopleFaceVid getPeopleFaceVid (@RequestParam(required = false, name = "vid") Long vid) {
        return peopleService.getPeopleFaceVid(vid);
    }


    @ApiOperation(value = "实有人口-同步实有人口的vid置信信息")
    @PostMapping(value = "/syncPeopleVid")
    public void syncPeopleVid(){
        peopleService.syncPeopleVid();
    }


    @ApiOperation(value = "实有人口-实有人口迁入小区")
    @PostMapping(value = "/peopleMoveIn")
    @Log(info = "实有人口迁入小区",module = "实有人口",function = "更新")
    public Result peopleMoveIn(@RequestBody RealPeopleHouseMove realPeopleHouseMove) {
    	User user = getCurrentUser();
		if(user == null) {
			return Result.error(ResultCode.USER_UNLOGIN_ERROR.code(),ResultCode.USER_UNLOGIN_ERROR.msg());
		}
        return peopleService.moveIn(realPeopleHouseMove, user);
    }

    @ApiOperation(value = "实有人口-实有人口从小区迁出")
    @PostMapping(value = "/peopleMoveOut")
    @Log(info = "实有人口迁出小区",module = "实有人口",function = "更新")
    public Result peopleMoveOut(@RequestBody RealPeopleHouseMove realPeopleHouseMove) {
    	User user = getCurrentUser();
		if(user == null) {
			return Result.error(ResultCode.USER_UNLOGIN_ERROR.code(),ResultCode.USER_UNLOGIN_ERROR.msg());
		}
        return peopleService.moveOut(realPeopleHouseMove, user);
    }

    @ApiOperation(value = "查询实有人口迁入迁出记录")
    @GetMapping(value = "/peopleMoveHistory")
    @Log(info = "查询实有人口迁入迁出记录",module = "实有人口",function = "查询")
    public List<RealPeopleHouseMove> peopleMoveList(@RequestParam(name = "credentialNos") String credentialNo) {
        return peopleService.moveList(credentialNo);
    }

    @ApiOperation(value = "实有人口-手动绑定vid")
    @PostMapping(value = "/bindVid")
    public Result bindVid(@RequestBody PeopleSearchModel peopleSearch) {
        return peopleService.bindVid(peopleSearch);
    }

    @ApiOperation(value = "实有人口-手动解除绑定vid")
    @PostMapping(value = "/unbindVid")
    public Result unbindVid(@RequestBody PeopleSearchModel peopleSearch) {
        return peopleService.unbindVid(peopleSearch);
    }
    
    @ApiOperation(value = "实有人口-数据迁移到ES-basedata索引")
    @GetMapping(value = "/syncDataToEs")
    public Result syncDataToEs() {
        try {
			return peopleService.syncDataToEs(null, null);
		} catch (Exception e) {
			log.error("实有人口历史数据迁移到ES-basedata索引异常:", e);
			return Result.error(ResultCode.ERROR);
		}
    }
    
    @ApiOperation(value = "新增人房关系")
    @PostMapping(value = "/insertPeopleHouse")
    public Result insertPeopleHouse(@RequestBody List<HouseDto> list) {
        return peopleService.insertPeopleHouse(list);
    }

}
